package com.derbysoft.lowcostadapter.dswitch2.handler;

import com.derbysoft.lowcostadapter.commons.log.Direction;
import com.derbysoft.lowcostadapter.commons.log.LogDetailPair;
import com.derbysoft.lowcostadapter.commons.log.TransactionLogger;
import com.derbysoft.lowcostadapter.commons.model.OperationType;
import com.derbysoft.lowcostadapter.commons.model.ReservationLog;
import com.derbysoft.lowcostadapter.dswitch2.service.HotelProviderService;
import com.derbysoft.lowcostadapter.dswitch2.service.helper.Constant;
import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.core.GenericRS;
import com.derbysoft.remote.dswitch.hotel.dto.CancelRQ;
import com.derbysoft.remote.dswitch.hotel.dto.CancelRS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by: jason
 * Date: 2012-06-01
 */
@Service("ds2HotelCancelHandler")
public class HotelCancelHandler  extends AbstractDSwitch2Handler
        implements RemoteServiceHandler<GenericRQ<CancelRQ>, GenericRS<CancelRS>> {

    @Autowired
    @Qualifier("ds2CancelService")
    private HotelProviderService<GenericRQ<CancelRQ>, GenericRS<CancelRS>> hotelProviderService;

    @Override
    public GenericRS<CancelRS> handle(GenericRQ<CancelRQ> request) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        TransactionLogger.getReservationLogger().set(createReservationLog(request));

        GenericRS<CancelRS> response = hotelProviderService.invoke(request);

        stopWatch.stop();

        long elapsedTime = stopWatch.getTotalTimeMillis();

        if (Boolean.valueOf(loadSystemVariable(Constant.APPEND_DERBY_LOG).getValue())) {
            appendLogDetail(request, response);
        }
        TransactionLogger.getReservationLogger().get().setTimeSpan(elapsedTime);
        return response;
    }

    private void appendLogDetail(GenericRQ<CancelRQ> request, GenericRS<CancelRS> response) {
        Set<LogDetailPair> logDetails = TransactionLogger.getLogDetails().get();
        if (logDetails == null) {
            logDetails = new HashSet<LogDetailPair>();
        }
        logDetails.add(LogDetailPair.build(request, Direction.FROM_CHANNEL));
        logDetails.add(LogDetailPair.build(response, Direction.TO_CHANNEL));
        TransactionLogger.getLogDetails().set(logDetails);
    }

    protected ReservationLog createReservationLog(GenericRQ<CancelRQ> request) {
        ReservationLog reservationLog = new ReservationLog();
        reservationLog.setTaskId(request.getHeader().getTaskId());
        reservationLog.setChannel(request.getHeader().getSource().getUniqueID().getId());
        reservationLog.setErsp(ReservationIDUtils.getErspNo(request.getPayload().getHotelReservationIDs()).getResIDValue());
        reservationLog.setOperationType(OperationType.CANCELLATION);
        return reservationLog;
    }
}
